<template>
  <div>
    <input
      class="uploadFile"
      type="file"
      ref="fileInput"
      @change="uploadFile($event.target)"
      :accept="accept"
      :multiple="multiple"
    />
    <div :class="isWrap ? 'upload_pictures is_wrap' : 'upload_pictures'">
      <div
        v-if="fileLists.length < maxNum && type == 'upload'"
        class="upload_btn"
        @click="uploadFiless"
      >
        <img class="img_add" src="@/assets/images/add.png" alt="加载失败" />
        <div class="upload_txt">{{ uploadTypeText[uploadType] }}</div>
      </div>
      <div
        v-for="(item, index) in fileLists"
        v-if="item.type == 2 || item.type == 1"
        :key="index"
        style="width: 102px"
      >
        <div class="view_img" v-if="item.type == 2 || item.type == 1">
          <el-image
            v-if="item.type == 1"
            class="view_img_url"
            :src="item.url"
            :preview-src-list="[item.url]"
          >
          </el-image>
          <div v-if="item.type == 2" class="video_box">
            <img
              class="video_img"
              src="@/assets/images/video_img.png"
              alt="加载失败"
            />
            <video-review
              class="video_box"
              ref="videoReview"
              :videoSrc="item.url"
            ></video-review>
          </div>
          <img
            v-if="type == 'upload'"
            @click.stop="delImg(index)"
            class="close_img"
            src="@/assets/images/close_img.png"
            alt="加载失败"
          />
        </div>
        <div class="view_text rela" v-if="isShowName">
          <tooltip :text="item.name" width="100%"></tooltip>
        </div>
      </div>
    </div>
    <div
      class="new_file rela"
      v-for="(item, index) in fileLists"
      :key="index"
      v-show="item.type == 3 || item.type == 4"
    >
      <img
        v-if="type == 'upload'"
        @click="delImg(index)"
        class="close_img"
        src="@/assets/images/close_img.png"
        alt="加载失败"
      />
      <div @click="lookFiles(item.url, item.name)" class="other_box rela">
        <img class="icon_img" :src="returnIcon(item.url, 1)" alt="加载失败" />
        <div class="other_text rela">
          <tooltip position="top" :text="item.name" width="100%" />
          <!-- {{ item.name.slice(item.name.lastIndexOf('.'), item.name.length) }} -->
        </div>
      </div>
    </div>
    <fileDrawer
      :downloadAbled="downloadAbled"
      :show.sync="drawer"
      :url="drawerurl"
      :name="drawername"
      :type="drawertype"
    ></fileDrawer>
  </div>
</template>

<script>
import { fammterString, uploadOSS } from "@/api/upload";
import videoReview from "@/components/videoReview/videoReview";
import fileDrawer from "@/components/fileDrawer.vue";
import { returnIcon, getUniqueFileName } from "@/utils/util.js";

export default {
  props: {
    multiple: {
      type: Boolean,
      default: false,
    },
    type: {
      type: String,
      default: "upload",
    },
    maxImageSize: {
      type: Number,
      default: 5, // 默认最大图片大小为5MB
    },
    maxVideoSize: {
      type: Number,
      default: 50, // 默认最大视频大小为50MB
    },
    maxFileSize: {
      type: Number,
      default: 10, // 默认最大文件大小为10MB
    },
    //oss直传附件类型，没有则直接上传
    ossType: {
      type: [Number, String],
      default: "", // 默认最大图片大小为5MB
    },
    accept: {
      type: [String],
      default: "*", // 默认最大图片大小为5MB
    },
    maxNum: {
      type: [String, Number],
      default: "3", // 默认最多图片为3张
    },
    uploadType: {
      type: [String, Number],
      default: "3", // 默认上传类型为3
    },
    uuid: {
      type: [String],
      default: "", // 默认上传类型为3
    },
    echoFile: {
      type: Array,
      default: [], // 回显文件列表
    },
    isWrap: {
      type: Boolean,
      default: false, // 上传视频是否换行
    },
    isShowName: {
      type: Boolean,
      default: false, // 是否展示文件名
    },
    // 添加课程的时候 可下载文件
    downloadAbled: {
      type: Boolean,
      default: false,
    },
  },
  components: {
    videoReview,
    fileDrawer,
  },
  watch: {
    echoFile: {
      handler(val) {
        this.fileLists = val;
      },
    },
  },
  created() {
    if (this.echoFile.length > 0) {
      this.fileLists = this.echoFile;
    }
  },
  data() {
    return {
      drawer: false,
      drawerurl: "",
      drawername: "",
      drawertype: "",
      uploadTypeText: {
        1: "上传图片",
        2: "上传视频",
        3: "上传文件",
      },
      fileLists: [],
    };
  },
  methods: {
    returnIcon: function (url, type) {
      return returnIcon(url, type);
    },
    lookFiles(url, name) {
      let uploadType = url
        .slice(url.lastIndexOf("."), url.length)
        .toLowerCase();
      let arr = [
        ".gif",
        ".png",
        ".jpeg",
        ".jpg",
        ".mp4",
        ".webm",
        ".pdf",
        ".wps",
        ".docx",
        ".doc",
        ".rtf",
        ".pptx",
        ".ppt",
        ".xls",
        ".xlsx",
        ".wps",
        ".ofd",
        ".txt",
        ".js",
        ".json",
        ".css",
        ".sql",
        ".xml",
        ".java",
        ".cs(c#)",
      ];
      if (arr.indexOf(uploadType) > -1) {
        this.drawer = true;
        this.drawerurl = url;
        this.drawername = name;
        this.drawertype = 1;
      } else {
        window.open(url, "_blank");
      }
    },
    uploadFiless() {
      const fileInput = this.$refs.fileInput;
      fileInput.click();
    },
    uploadFile(event) {
      if (
        this.echoFile.length + this.$refs.fileInput.files.length >
        this.maxNum
      ) {
        this.$message.error("最多上传" + this.maxNum + "个文件");
        return;
      }
      let files = this.$refs.fileInput.files;
      for (let i = 0; i < files.length; i++) {
        let file = this.$refs.fileInput.files[i];
        const fileType = file.type.split("/")[0];
        console.log(fileType, "fileType");
        const fileSize = file.size / 1024 / 1024; // 转换为MB
        if (fileType === "image" && fileSize > this.maxImageSize) {
          this.$modal.msgWarning(`图片大小不能超过${this.maxImageSize}MB`);
          return;
        }
        if (fileType === "video" && fileSize > this.maxVideoSize) {
          this.$modal.msgWarning(`视频大小不能超过${this.maxVideoSize}MB`);
          return;
        }
        let mediaType = ["video", "image"];
        if (mediaType.indexOf(fileType) == -1 && fileSize > this.maxFileSize) {
          this.$modal.msgWarning(`文件大小不能超过${this.maxFileSize}MB`);
          return;
        }
      }
      this.uploadFiles(event, files);
      // 进行上传操作
    },
    async uploadFiles(event, files) {
      let imgTypes = [".png", ".jpg"];
      let videoTypes = [".mp4", ".webm"];
      let wordPdfPptTypes = [".pdf", ".doc", ".docx", ".pptx"];
      // 收集所有已存在的文件名（来自已上传 + 回显）
      const existingNames = this.echoFile.map((f) => f.name);
      const uploadPromises = Array.from(files).map(async (file) => {
        const uploadType = file.name.slice(
          file.name.lastIndexOf("."),
          file.name.length
        );
        let type;

        if (imgTypes.includes(uploadType.toLowerCase())) {
          type = 1;
        } else if (videoTypes.includes(uploadType.toLowerCase())) {
          type = 2;
        } else if (wordPdfPptTypes.includes(uploadType.toLowerCase())) {
          type = 3;
        } else {
          type = 4;
        }
        // 使用外部引入的重命名函数
        const uniqueFileName = getUniqueFileName(existingNames, file.name);
        // 创建重命名后的 File 对象
        const renamedFile = new File([file], uniqueFileName, { type: file.type });
        let res;
        try {
          if (this.ossType) {
            const path = fammterString(this.ossType, this.uuid);
            res = await uploadOSS(renamedFile, path);
          } else {
            res = await uploadOSS(renamedFile);
          }
          // 上传成功，返回文件对象
          return {
            type,
            name: uniqueFileName,
            url: res[0], // 假设 res 是数组，取第一项
          };
        } catch (e) {
          console.error(`文件上传失败: ${uniqueFileName}`, e);
          // 可选：失败的文件是否仍保留在列表中？比如标记 error
          return {
            type,
            name: uniqueFileName,
            url: null,
            error: true,
          };
        }
      });

      try {
        // 等待所有上传完成
        const results = await Promise.all(uploadPromises);

        // 过滤掉上传失败且不需要显示的文件（可选）
        const successfulFiles = results.filter((item) => item.url); // 只保留成功上传的
        // 或者如果你想保留所有（包括失败的），直接用 results

        // 更新 fileLists
        this.fileLists.push(...successfulFiles); // 或者 results

        // 所有上传完成后再 emit
        this.$emit("uploadFiles", this.fileLists);
      } catch (e) {
        // 注意：Promise.all 一旦有一个 reject 就会走 catch
        // 如果你不希望失败一个就中断，上面的 try/catch 已经处理了每个文件，这里就不会报错
        // 所以上面每个 promise 内部捕获了错误，Promise.all 不会 reject
        console.error("批量上传过程中有文件失败", e);
        // 但由于每个错误已被单独处理，这里通常不会走到
      }
      this.$emit("uploadFiles", this.fileLists);
      //重置input
      event.value = "";
    },
    delImg(index) {
      this.fileLists.splice(index, 1);
      this.$emit("uploadFiles", this.fileLists);
    },
  },
};
</script>
<style lang="scss" scoped>
.uploadFile {
  display: none;
}

.upload_pictures {
  gap: 0 10px;
  width: 100%;
  flex-wrap: wrap;
  display: flex;
  justify-content: flex-start;
}

.is_wrap {
  flex-wrap: wrap;
}

.upload_btn {
  width: 102px;
  height: 102px;
  border-radius: 8px;
  border: 1px dashed #b8c4d1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.img_add {
  width: 20px;
  height: 20px;
}

.upload_txt {
  margin-top: 23px;
  line-height: 1;
  text-align: center;
  font-size: 14px;
  font-weight: 400;
  color: #999;
}

.view_img {
  width: 102px;
  height: 102px;
  border-radius: 8px;
  margin-right: 12px;
  position: relative;
}

.view_text {
  width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 14px;
  color: #565656;
  margin: 10px 0;
}

.view_img_url {
  width: 100%;
  height: 100%;
}

.video_box {
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  background: #f5f5f5;
  border-radius: 8px;
  cursor: pointer;
}

.video_img {
  width: 24px;
  height: 24px;
  object-fit: cover;
  position: absolute;
}

.close_img {
  width: 16px;
  height: 16px;
  position: absolute;
  top: -4px;
  right: -4px;
  cursor: pointer;
}

.new_file {
  display: flex;
  flex-direction: column;
  position: relative;

  margin-top: 20px;

  .other_box {
    height: 100%;
    display: flex;
    border-radius: 8px;
    align-items: flex-end;
    cursor: pointer;

    .icon_img {
      width: 40px;
      height: 40px;
      margin-right: 10px;
    }

    .other_text {
      width: 200px;
      font-size: 14px;
      color: #565656;
      display: flex;
      align-items: center;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
  }

  .close_img {
    width: 16px;
    height: 16px;
    position: absolute;
    top: -10px;
    right: -10px;
    cursor: pointer;
  }
}
</style>
